package org.example.shiro.controller;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.annotation.*;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;

@Controller
@RequestMapping("LoginController")
public class LoginController {
    /**
     * 跳转到登录页面
     */
    @GetMapping("login")
    public String login() {
        return "login";
    }

    // 登录认证
    @GetMapping("userLogin1")
    @ResponseBody
    public String userLogin(String name,String pwd){
        //1.获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        //2.封装请求数据到Token中
        AuthenticationToken token = new UsernamePasswordToken(name, pwd);
        //3.调用login方法进行登录认证
        try {
            subject.login(token);
            return "登录成功";
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("登录失败");
            return "登录失败";
        }
    }

    /**
     * 登录认证:登录成功后从login.html跳转到main.html,并且把信息放到Session里面
     * 因为不需要返回数据,所以去掉@ResponseBody注解
     * @param name
     * @param pwd
     * @return
     */
    @GetMapping("userLogin")
    public String userLogin(String name, String pwd, HttpSession session, @RequestParam(required = false)Boolean rememberMe){
        //1.获取Subject对象
        Subject subject = SecurityUtils.getSubject();
        //2.封装请求数据到Token中
        AuthenticationToken token = new UsernamePasswordToken(name, pwd,rememberMe);
        //3.调用login方法进行登录认证
        try {
            subject.login(token);
            //将用户信息放入session
            session.setAttribute("user",token.getPrincipal().toString());
            //跳转到main.html
            return "main";
        }catch (Exception e){
            e.printStackTrace();
            System.out.println("登录失败");
            return "登录失败";
        }
    }
    @GetMapping("/show")
    //验证用户是否登录，等同于方法subject.isAuthenticated()
    //@RequiresAuthentication
    //@RequiresUser : 验证用户是否被记忆，登录认证成功subject.isAuthenticated() 为true，登录后被记忆subject.isRemembered()为true
    //@RequiresUser
    //@RequiresGuest : 验证是否是一个 guest 游客的请求，此时subject.getPrincipal()为 null
    //@RequiresRoles ：验证subject是否有相应角色，有角色访问方法，没有则会抛出异常AuthorizationException
    // 只有subject有aRoleName角色才能访问方法someMethod()
    //@RequiresRoles("aRoleName")

    //@RequiresPermissions：验证 subject 是否有相应权限，有权限访问方法，没有则会抛出异常 AuthorizationException
    //@RequiresPermissions({"file:read","write:a.txt"})
    public String show(HttpSession session){
        Subject subject = SecurityUtils.getSubject();
        session.setAttribute("user",subject.getPrincipal().toString()+":"+org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        System.out.println(org.apache.shiro.codec.Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
        return "main.html";
    }

    /**
     * 授权admin角色
     * @return
     */
    @RequiresRoles({"admin"})
    @GetMapping("userLoginRoles")
    @ResponseBody
    public String userLoginRoles() {
        System.out.println("登录认证验证角色");
        return "验证角色成功";
    }

    /**
     * 根据用户获取用户角色的权限信息,验证是否具有 user:delete 权限
     * @return
     */
    @RequiresPermissions("user:delete")
    @GetMapping("userPermissions")
    @ResponseBody
    public String userLoginPermissions() {
        System.out.println("登录认证验证权限");
        return "验证权限成功";
    }

}
